﻿using System;
using System.Data.Linq;
using System.Linq;

namespace Common.Linq
{
    public class LinqToSqlProvider<TElement> : IProvider<TElement>
        where TElement : class
    {
        private Object m_Sync = new Object();
        private Table<TElement> m_Table;
        private ThreadSafeQueryable<TElement> m_Queryable;

        public LinqToSqlProvider(Table<TElement> table)
        {
            this.m_Table = table;
            this.m_Queryable = new ThreadSafeQueryable<TElement>(this.m_Table, this.m_Sync);
        }

        ~LinqToSqlProvider()
        {
            this.Dispose(false);
        }

        public IQueryable<TElement> Items
        {
            get { return this.m_Queryable; }
        }

        public void Add(TElement newElement)
        {
            lock (this.m_Sync)
            {
                this.m_Table.InsertOnSubmit(newElement);
            }
        }

        public void Delete(TElement newElement)
        {
            lock (this.m_Sync)
            {
                this.m_Table.DeleteOnSubmit(newElement);
            }
        }

        public void Clear()
        {
            lock (this.m_Sync)
            {
                foreach (TElement element in this.m_Table)
                {
                    this.m_Table.DeleteOnSubmit(element);
                }
            }
        }

        public void ApplyChanges()
        {
            lock (this.m_Sync)
            {
                this.m_Table.Context.SubmitChanges();
            }
        }

        #region IDisposable Members

        public void Dispose()
        {
            this.Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(Boolean disposing)
        {
            if (disposing)
            {
                this.m_Table.Context.Dispose();
                this.m_Table = null;
            }
        }

        #endregion
    }
}
